package com.itheima.app.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.itheima.autoconfig.AipFaceTemplate;
import com.itheima.autoconfig.HuanXinTemplate;
import com.itheima.autoconfig.OssTemplate;
import com.itheima.autoconfig.SmsTemplate;
import com.itheima.domain.db.Log;
import com.itheima.domain.db.User;
import com.itheima.domain.db.UserInfo;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.db.UserService;
import com.itheima.util.ConstantUtil;
import com.itheima.util.JwtUtil;
import com.itheima.vo.ErrorResult;
import com.itheima.vo.UserInfoVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.security.Security;
import java.time.Duration;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author zsk
 * @create 2022-03-13-16:17
 */
@Component
public class UserManager {

    @DubboReference
    private UserService userService;

    @Autowired//调用阿里云生成短信验证码
    private SmsTemplate smsTemplate;

    @Autowired//存储Redis
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private AipFaceTemplate aipFaceTemplate;

    @Autowired
    private OssTemplate ossTemplate;

    @DubboReference
    private UserInfoService userInfoService;

    @Autowired
    private HuanXinTemplate huanXinTemplate;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    //新增用户
    public ResponseEntity save(User user) {
        //调用service层查询
        Long userId = userService.save(user);
        //返回主键id
        return ResponseEntity.ok(userId);// 状态码200，响应体数据 101 用户id
    }

    //查询用户(根据手机)
    public ResponseEntity findByPhone(String phone) {

        //调用service查询
        User user = userService.findByPhone(phone);
        //返回结果
        return ResponseEntity.ok(user);// 状态码200，响应体数据 {xxx:xxx} 用户对象
    }

    //发送验证码
    public void sendSms(String phone) {
        //使用糊涂包生成验证码
        String smsCode = RandomUtil.randomNumbers(6);
        //前期先写死
        smsCode = "123456";

        //调用阿里云发送短信
        //smsTemplate.sendSms(phone,smsCode); //todo 等上线在使用

        //存储到Redis中(有限时间5分钟)
        stringRedisTemplate.opsForValue().set(ConstantUtil.SMS_CODE + phone, smsCode, Duration.ofMinutes(5));

    }

    //登录/注册
    public ResponseEntity loginVerification(String phone, String verificationCode) {

        //取出Redis的验证码
        String redisCode = stringRedisTemplate.opsForValue().get(ConstantUtil.SMS_CODE + phone);
        //比对验证码
        if (!StringUtils.equals(verificationCode, redisCode)) {
            //如果不相等(报500异常，然后回显前端错误提示，验证码异常)
            return ResponseEntity.status(500).body(ErrorResult.loginError());
        }
        //根据手机号查询用户
        User user = userService.findByPhone(phone);
        //创建一个Boolean常量
        Boolean isNew;
        String type = null;
        //如果user不为null则代表是老用户
        if (user != null) {
            isNew = false;//直接登录
            type = "0101";//0101代表登录
        }else {
            isNew = true;//代表新用户
            //新建一个User对象填充信息
            user = new User();
            user.setMobile(phone);
            //密码加密
            user.setPassword(ConstantUtil.INIT_PASSWORD);
            //调用service保存新用户
            Long userId = userService.save(user);
            //设置新用户的id
            user.setId(userId);

            //注册环信
            huanXinTemplate.register("HX" + userId);

            type = "0102";//代表注册

        }

        //jwt制作令牌
        //先将密码设置为空，不想给前台返回显示
        user.setPassword(null);
        //将user对象转换为Map集合
        Map<String, Object> claims = BeanUtil.beanToMap(user);
        String token = JwtUtil.createToken(claims);
        //使用Redis存储令牌，保存7天
        String json = JSON.toJSONString(user);//将user数据转换为json数据
        stringRedisTemplate.opsForValue().set(ConstantUtil.USER_TOKEN + token,json,Duration.ofDays(7));

        //删除Redis中的短信验证码
        stringRedisTemplate.delete(ConstantUtil.SMS_CODE + phone);

        // 封装log对象
        Log log = new Log();
        log.setUserId(user.getId());
        log.setLogTime(DateUtil.formatDate(new Date()));
        log.setPlace("北京顺义黑马程序员");
        log.setEquipment("小米10");
        log.setType(type);//登录或者注册

        //发送日志消息
        rabbitTemplate.convertAndSend("tanhua.log",log);

        //返回数据
        Map resultMap = new HashMap();
        resultMap.put("token",token);
        resultMap.put("isNew",isNew);
        return ResponseEntity.ok(resultMap);
    }

    //用户首次登录补全信息
    public void loginReginfo(UserInfo userInfo, String token) {

        //解析token获取User信息
        User user = findUserByToken(token);
        //将userId设置到userInfo中
        userInfo.setId(user.getId());
        //调用rpc保存
        userInfoService.loginReginfo(userInfo);

    }

    //解析token获取User对象，供其他方法调用
    public User findUserByToken(String token){
        //检测Redis中是否存在token
        Boolean isCheck = stringRedisTemplate.hasKey(ConstantUtil.USER_TOKEN + token);
        if (isCheck == true){//存在，登录
            //获取用户信息
            String json = stringRedisTemplate.opsForValue().get(ConstantUtil.USER_TOKEN + token);
            //转换为User对象
            User user = JSON.parseObject(json, User.class);
            //续期7天
            stringRedisTemplate.opsForValue().set(ConstantUtil.USER_TOKEN + token,json,Duration.ofDays(7));
            //返回对象
            return user;
        }
        //Redis中不存在，代表未登录
        return null;
    }

    //头像上传
    public ResponseEntity loginReginfoHead(MultipartFile headPhoto, String token) throws IOException {
        //人脸检测
        boolean detect = aipFaceTemplate.detect(headPhoto.getBytes());

        if (detect == false){//表示不是人脸
            return ResponseEntity.status(500).body(ErrorResult.faceError());//返回状态码专属错误
        }
        //人像上传
        String pirUrl = ossTemplate.upload(headPhoto.getOriginalFilename(), headPhoto.getInputStream());

        //解析token
        User user = findUserByToken(token);
        //封装userInfo对象
        UserInfo userInfo = new UserInfo();
        userInfo.setId(user.getId());//id
        userInfo.setAvatar(pirUrl);//头像
        userInfo.setCoverPic(pirUrl);//封面
        //调用rpc更新
        userInfoService.update(userInfo);
        //返回结果
        return ResponseEntity.ok(null);

    }

    //根据id查询用户
    public ResponseEntity findUserInfoVo(Long userId) {
        //调用service查询
        UserInfo userInfo = userInfoService.findById(userId);
        //因为前端与数据库字段属性不一致，所以封装vo对象
        UserInfoVo vo = new UserInfoVo();
        //使用工具类封装对象
        BeanUtil.copyProperties(userInfo,vo);
        //返回vo对象
        return ResponseEntity.ok(vo);
    }

    //更新用户信息
    public void putUserInfo(UserInfo userInfo) {
        //调用rpc更新
        userInfoService.update(userInfo);

    }
}
